﻿using System;
using System.Net;
using Platformer_Example.Controller.Character.Player;
using Platformer_Example.Controller.Input;
using Platformer_Example.Controller.Map;
using Platformer_Example.Controller.Network;
using Platformer_Example.Controller.Network.Messages;
using Platformer_Example.Screen.Common;
using System.Linq;
using Transformable_Engine_v2.Engine.Input;
using Transformable_Engine_v2.Engine.Rendering;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Platformer_Example.Screen.Playscreen
{
    public class Playscreen : BaseScreen
    {
        private readonly NetworkClient _client;
        private readonly ClientData _clientData;
        private MapData _map;

        private readonly NetworkServer _server;
        private readonly ServerData _serverData;

        public static Player LocalPlayer { get; private set; }

        public Playscreen(NetworkServer server, ServerData serverData, MapData map)
        {
            _server = server;
            _serverData = serverData;
            _server.OnInputPressed += OnServerInputPressed;
            _server.OnInputReleased += OnServerInputReleased;

            LocalPlayer = map.LocalPlayer;

            AddLoadedObjectsToPlayscreen(map);
        }

        private void OnServerInputReleased(InputReleased message, IPAddress senderaddress)
        {
            Guid id = Guid.Parse(message.PlayerId);
            _server.SendInputReleased(_serverData.ClientAddressesBut(id), id, message.Key);
            _map.Players[id].InputReleased(message.Key);
        }

        private void OnServerInputPressed(InputPressed message, IPAddress senderaddress)
        {
            Guid id = Guid.Parse(message.PlayerId);
            _server.SendInputPressed(_serverData.ClientAddressesBut(id), id, message.Key);
            _map.Players[id].InputPressed(message.Key);
        }

        public Playscreen(NetworkClient client, ClientData clientData, MapData map)
        {
            _client = client;
            _clientData = clientData;
            _client.OnInputPressed += OnClientInputPressed;
            _client.OnInputReleased += OnClientInputReleased;

            AddLoadedObjectsToPlayscreen(map);
        }

        private void OnClientInputReleased(InputReleased message, IPAddress senderaddress)
        {
            Guid id = Guid.Parse(message.PlayerId);
            _map.Players[id].InputReleased(message.Key);
        }

        private void OnClientInputPressed(InputPressed message, IPAddress senderaddress)
        {
            Guid id = Guid.Parse(message.PlayerId);
            _map.Players[id].InputPressed(message.Key);
        }

        private void AddLoadedObjectsToPlayscreen(MapData map)
        {
            ViewHandler.AddView("playscreenView", new TE_Rectangle(0, 0, 2, 2));
            _map = map;

            AddChildren(map.Maps.Select(x => x.Value).ToArray());
        }


        public override void Draw()
        {
            ViewHandler.SetView("playscreenView");
            _map.LocalPlayer.Map.Draw();
            ViewHandler.RevertToDefaultView();
        }

        public override void Keypressed(InputState.Key key)
        {
            if (_map.LocalPlayer.InputPressed(key))
            {
                if (_server != null)
                    _server.SendInputPressed(_serverData.ClientAddresses(), _serverData.LocalPlayer, key);
                else
                    _client.SendInputPressed(_clientData.ServerIPAddress, _clientData.Id, key);
            }
        }

        public override void KeyReleased(InputState.Key key)
        {
            if (_map.LocalPlayer.InputReleased(key))
            {
                if (_server != null)
                    _server.SendInputReleased(_serverData.ClientAddresses(), _serverData.LocalPlayer, key);
                else
                    _client.SendInputReleased(_clientData.ServerIPAddress, _clientData.Id, key);
            }
        }

        public override void InvalidKeyPressed(KeyboardInput.Key keyCode)
        {
        }
    }
}